今天要介紹的是生成模式中的 builder (生成器模式)
這模式的目的是從複雜物件的布局中抽取生成程序,以便於可以使用同一個生成程序來製造各種不同的物件布局。
白話一點的方式就是說,若今天有一個生成起來會很複雜的大物件,或是需要很多前置步驟才能完整生成的物件,我可以把他們的生成程序抽出來,全部放到 builder 裡面,把它們包成介面,所有在builder上的介面會包含所有生成大物件所需的程序。當我今天要生成這類大型物件,我就可以產生一個builder,設定好我要的生成的一些參數,最後直接從builder手上拿到我期望看到的物件。而這個builder中的介面若是虛擬函數,我就可以拿它來繼承,覆寫並衍生新的builder,獲取不同種的大型物件。
白話解釋之後,其實還是很複雜...(我覺得)
我們直接拿一個現實實例來比喻好了
我覺得builder就有點像比較日本會有的那種現代化現做食物販賣機,裡面的機械化烹飪設施
烹飪應該算是複雜的流程吧?
把烹飪的工作抽出來丟給烹飪機器做,你設計的販賣機就不用管什麼碗物件、鍋子物件、撈麵用的勺子物件,你只管拿到客人要的餐點還有針對個人的產品客製化,這個時候烹飪機器就是一個builder物件!
class foodBuilder {
public:
virtual void takeMaterial();
virtual void cookTheMeal();
virtual void putToContainer();
virtual void doSeasoning();
food* getFood();
};
這裡把foodBuilder的每個製造流程都定義為virtual,
這樣我們就可以拿它來繼承並實作其他食物的製作
假設今天實作了麵的製造流程
class noodleBuilder : public foodBuilder {
void takeMaterial() override;
void cookTheMeal() override;
void putToContainer() override;
void doSeasoning() override;
};
販賣機今天裡面裝了一台熱食製造機
因為builder模式強調生成程序的抽出集中管理,因此一個採用foodBuilder的食物販賣機,不用考慮備料、如何烹煮、要準備什麼器材等等,只需要知曉一套標準化的食物製造流程,還有一個可以讓顧客點餐的介面。
class vendingMachine(){
public:
enum sellingFood { Noodle, Rice }; /*定義販賣機只有賣飯跟麵*/
food* order(sellingFood* food){ /*定義客人看的到的點餐介面*/
switch(food){
case Noodle :
foodBuilder* builder = new noodleBuilder;
return cookCustomersMeal(builder);
case Rice :
/* 以下省略 */
}
}
private:
food* cookCustomersMeal(foodBuilder* builder){ /*定義如何呼叫foodBuilder的介面*/
builder->takeMateral();
builder->cookTheMeal();
builder->putToContainer();
builder->doSeasoning();
return builder->getFood();
}
};
如果顧客去買販賣機的東西...
只會有點餐和取餐的步驟,其他看不到
int main(){
vendingMachine* machine = new vendingMachine;
food* f;
f = machine->order(vendingMachine::Noodle);
return 0;
}
以上就是生成模式中 builder (生成者模式) 的介紹